package br.com.linhadotempo.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;

import br.com.linhadotempo.persistence.GerarEntityManager;
import br.com.linhadotempo.util.Mensagens;

public abstract class DaoMestre<T> implements DaoInterface<T> {

	private EntityManager em;

	public DaoMestre() {
		GerarEntityManager.getInstance();
		em = GerarEntityManager.getEntityManager();
	}

	public EntityManager getEm() {
		return em;
	}

	public void setEm(EntityManager em) {
		this.em = em;
	}

	@Override
	public void incluir(T arg) {
		try {
			em.getTransaction().begin();
			em.persist(arg);
			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			Mensagens.getInstance().setError(e.getCause().getMessage());
		} finally {
			em.close();
		}
	}

	@Override
	public void alterar(T arg) {
		try {
			em.getTransaction().begin();
			em.merge(arg);
			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			Mensagens.getInstance().setError(e.getCause().getMessage());
		} finally {
			em.close();
		}
	}

	@Override
	public void remover(Integer id) {
		try {
			em.getTransaction().begin();
			em.remove(get(id));
			em.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			Mensagens.getInstance().setError(e.getCause().getMessage());
		} finally {
			em.close();
		}
	}

	@Override
	public T get(Integer id) {
		try {
			return em.find(getClasse(), id);
		} catch (Exception e) {
			e.printStackTrace();
			Mensagens.getInstance().setError(e.getCause().getMessage());
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public Class<T> getClasse() {
		try {
			return (Class<T>) ((ParameterizedType) getClass()
					.getGenericSuperclass()).getActualTypeArguments()[0];
		} catch (Exception e) {
			e.printStackTrace();
			Mensagens.getInstance().setError(e.getCause().getMessage());
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> searchTheDatabase(String sql, String param) {
		return em.createQuery(sql).setParameter(1, param).getResultList();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<T> searchTheDatabaseNativeSQL(String sql, String param) {
		return em.createNativeQuery(sql).setParameter(1, param).getResultList();
	}

}
